package com.chenjt.jvm.second.five_classLoader;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

/**
 * 注释：
 *
 * @author chenjt
 * @date 2025/7/2 14:57
 */
public class UserClassLoader extends ClassLoader{

    private String rootDir;

    public UserClassLoader(String rootDir){
        this.rootDir = rootDir;
    }

    /**
     * 编写findClass方法的逻辑
     * @param name
     *         The <a href="#name">binary name</a> of the class
     *
     * @return
     * @throws ClassNotFoundException
     */
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException{
        // 获取类的class文件字节数组
        byte[] classData = getClassData(name);
        if(classData == null){
            throw new ClassNotFoundException();
        }else{
            // 直接生成class对象
            return defineClass(name,classData, 0, classData.length);
        }
    }


    /**
     * 编写获取class文件并转换为字节码流的逻辑
     * @param className
     * @return
     */
    private byte[] getClassData(String className){
        // 读取类文件的字节
        String path = classNameToPath(className);

        try {
            InputStream ins = new FileInputStream(path);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            // 读取类文件的字节码
            while((len = ins.read(buffer)) != -1){
                baos.write(buffer,0,len);
            }
            return baos.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }


    /**
     * 类文件的完全路径
     * @param className
     * @return
     */
    private String classNameToPath(String className){
        return rootDir + "\\" + className.replace('.','\\') + ".class";
    }


    public static void main(String[] args) {
        /**
         * 这里加载的是该类同目录下User.class这个字节码文件
         * 所以需要在该目录下先编译 javac User.java
         */
        String rootDir = "D:\\programmer\\studyWorkspace\\JVM\\src\\";

        try {
            UserClassLoader loader1 = new UserClassLoader(rootDir);
            Class clazz1 = loader1.findClass("com.chenjt.jvm.second.five_classLoader.User");

            UserClassLoader loader2 = new UserClassLoader(rootDir);
            Class clazz2 = loader2.findClass("com.chenjt.jvm.second.five_classLoader.User");

            // clazz1与clazz2对应了不同的类模板结构
            System.out.println(clazz1 == clazz2);// false
            System.out.println(clazz1.getClassLoader());// com.chenjt.jvm.second.five_classLoader.UserClassLoader@1b6d3586
            System.out.println(clazz2.getClassLoader());// com.chenjt.jvm.second.five_classLoader.UserClassLoader@74a14482


            // 这里加载的是编译完out路径下的User类
            Class clazz3 = ClassLoader.getSystemClassLoader().loadClass("com.chenjt.jvm.second.five_classLoader.User");
            System.out.println(clazz3.getClassLoader());// sun.misc.Launcher$AppClassLoader@18b4aac2

        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }

    }



}
